<?php
if(!defined('SYSTEM_PATH')) die('Cannot access this page directly or see your configuration file ') ;
/**
 * Database
 *
 * @package cosmoClan Database
 * @author menTiss - Staff SeS
 * @copyright 2007-2008
 * @version 0.1.1
 * @since 0.1.0 added comments, updated methods, optimized the use of benchmark classe
 * @access public
 **/
class Database extends Cosmo {
	private $_driver 	= false;
	private $_nbQuery 	= 0 ;
	private $template ;
	private $bench ;

	/**
	 * Database::__construct()
	 *
	 * @desc construct the object
	 **/
	public function __construct() {
		parent::__construct() ;
		$this->template 	= $this->load->object('template') ;
		$lang 			= $this->load->language('database') ;
		$this->template->assign('lang',$lang) ;
		unset($lang) ;
		$this->bench  		= $this->load->object('benchmark') ;
	}
	/**
	 * Database::setDriver()
	 *
	 * @desc Allow to set the driver to use
	 * @param object $driver
	 * @return
	 **/
	public function setDriver(&$driver) {
		if(is_a($driver,'DatabaseDriver')) {
			$this->_driver =& $driver ;
			return true;
		}
		return false;
	}
	/**
	 * Database::getCursor()
	 *
	 * @desc Return the actual link for the database
	 * @return
	 **/
	public function getLink() {
		if(!$this->_driver) return false ;
		return $this->_driver->getLink() ;
	}
	/**
	 * Database::__destruct()
	 *
	 **/
	public function __destruct() {
		if($this->_driver) return $this->close() ;
	}
	/**
	 * Database::close()
	 *
	 * @desc Close a database connexion
	 * @return
	 **/
	public function close() {
		if(!$this->_driver) return false ;
		return $this->_driver->close() ;
	}
	/**
	 * Database::connect()
	 *
	 * @desc Allow to connect to a database
	 * @return
	 **/
	public function connect() {
		if(!$this->_driver) return false ;
		$this->bench->setMarker('database') ;
		$this->_driver->connect() ;
		$this->bench->setMarker('database') ;
		$this->bench->getBench('database', true) ;
		if($this->_driver->isError()) {
			$this->displayError() ;
		}
		return $res ;
	}
	/**
	 * Database::query()
	 *
	 * @desc Execute a query on the database and return a result object of the driver type
	 * @param string $sql
	 * @return object
	 **/
	public function query($sql) {
		if(!$this->_driver) return false ;
		$this->_nbQuery++ ;
		$this->bench->setMarker('database') ;
		$res = $this->_driver->query($sql) ;
		$this->bench->setMarker('database') ;
		$this->bench->getBench('database', true) ;
		if($this->_driver->isError())	$this->displayError() ;
		$result = $this->load->databaseResult($this->_driver->getDriverType()) ;
		$result->setIdQuery($res) ;
		return $result ;
	}
	/**
	 * Database::__call()
	 *
	 * @desc Allow to execute a method of the driver..
	 * @todo Verify if the method exists in the driver or not
	 * @param mixed $method
	 * @param mixed $params
	 * @return
	 **/
	public function __call($method,$params) {
		if(!$this->_driver) return false ;
		$this->bench->setMarker('database') ;
		$res = call_user_func_array(array($this->_driver, $method), $params) ;
		$this->bench->setMarker('database') ;
		$this->bench->getBench('database', true) ;
		if($this->_driver->isError())	$this->displayError() ;
		return $res ;
	}
	/**
	 * Database::insert()
	 *
	 * This method need to be switch on the driver !!!! We don't have to use special function for a database
	 *
	 * @desc Return a sql command (a string) which is clean of sql injection
	 * @warning This method does not allow to specify field name, in this case you need build a value array in the right order of the
	 * @param string $tableName
	 * @param array $values
	 * @return string
	 */
	public function insert($tableName, $values) {
		if(!is_string($tableName) ||!is_array($values)) return false;
		$sql = "INSERT INTO ".$tableName." VALUES(" ;
		for($i=0;$i<count($values);$i++) {
			$value = stripslashes($values[$i]);
			if(is_string($values[$i]))
				$sql .= "'".@mysql_real_escape_string($value)."'" ;
			else
				$sql .= @mysql_real_escape_string($value) ;
			if($i<(count($values)-1)) {
				$sql .= "," ;
			}
		}
		$sql .= ")" ;
		return $sql ;
	}
	/**
	 * Database::getNbQuery()
	 *
	 * @desc Return the actual number of query which have been sent to the database
	 * @return
	 **/
	public function getNbQuery() {
		return $this->_nbQuery ;
	}
	/**
	 * Database::getDriverType()
	 *
	 * @desc Return the driver type which is used at this time
	 * @return
	 */
	public function getDriverType() {
		if(!$this->_driver) return false;
		return $this->_driver->getDriverType() ;
	}
	/**
	 * Database::getLastId()
	 *
	 * @desc Return the last created id after an INSERT command
	 * @return
	 */
	public function getLastId() {
		if(!$this->_driver) return false;
		return $this->_driver->getLastId() ;
	}
	/**
	 * Database::displayError()
	 *
	 * @desc Display the error if needed
	 * @return (void)
	 **/
	public function displayError() {
		$this->template->remove_all() ;
		$this->template->add(HEADER_TEMPLATE) ;
		$this->template->assign('time', $this->bench->getTime('database')) ;
		$this->template->assign('nb_query', $this->getNbQuery()) ;
		$this->template->assign('error', $this->_driver->error()) ;
		if(($sql=$this->_driver->getLastQuery()) != null)
			$this->template->assign('sql', $sql) ;
		else
			$this->template->assign('sql', false) ;
		$this->template->add('error/database', true) ;
	}
}

?>